package com.shane.andtools.perf;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by shane
 */
public class DDStringBuilderProxy {

    private static final int INIT_CAPACITY_SHARED = 32;
    private static final int INIT_CAPACITY = 96;
    private static final int POOL_MAX_SIZE = 12;
    /** StringBuilder instance*/
    private static volatile SoftReferenceProxy<List<DDStringBuilder>> sStringBuilderPool = null;

    /**
     * get DDStringBuilder
     */
    public static DDStringBuilder getDDStringBuilder(){

        if(Doraemon.MODE_DEBUG != Doraemon.getRunningMode()) {
            makeSureSoftProxy();

            List<DDStringBuilder> pool = sStringBuilderPool.get();

            DDStringBuilder ret = null;
            if (pool != null && pool.size() < POOL_MAX_SIZE) {
                for (DDStringBuilder sb : pool) {
                    if (sb != null && sb.length() == 0 && !sb.isShared()) {
                        ret = sb;
                        break;
                    }
                }
            }

            if (null != ret) {
                ret.setShared(true);
                return ret;
            } else {
                DDStringBuilder builder = new DDStringBuilder(INIT_CAPACITY);
                if (pool != null && pool.size() < POOL_MAX_SIZE) {
                    synchronized (pool) {
                        builder.setShared(true);
                        pool.add(builder);
                    }
                }

                return builder;
            }
        }else{
            return new DDStringBuilder(INIT_CAPACITY_SHARED);
        }
    }

    public static int getDDStringBuilderPoolSize() {
        List<DDStringBuilder> pool = sStringBuilderPool.get();

        return pool == null ? 0 : pool.size();
    }

    /**
     * init the soft reference proxy
     */
    private static void makeSureSoftProxy(){

        if(null == sStringBuilderPool)
            synchronized (DDStringBuilderProxy.class) {

                if (null == sStringBuilderPool) {
                    sStringBuilderPool = new SoftReferenceProxy<>();
                    sStringBuilderPool.setCreator(new SoftReferenceProxy.Creator<List<DDStringBuilder>>() {
                        @Override
                        public List<DDStringBuilder> create() {
                            return new ArrayList<DDStringBuilder>();
                        }

                        @Override
                        public List<DDStringBuilder> validate(List<DDStringBuilder> ref){
                            if (ref == null) {
                                ref = new ArrayList<DDStringBuilder>();
                            }

                            return ref;
                        }
                    });
                }
            }
    }

}
